package com.itheima.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import com.alibaba.dubbo.config.annotation.Service;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.itheima.constant.MessageConstant;
import com.itheima.dao.MemberDao;
import com.itheima.dao.OrderDao;
import com.itheima.dao.OrderSettingDao;
import com.itheima.entity.PageResult;
import com.itheima.entity.QueryPageBean;
import com.itheima.entity.Result;
import com.itheima.exception.OrderException;
import com.itheima.pojo.*;
import com.itheima.service.OrderService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * @author liam
 * @description
 * @date 2020/3/2-19:41
 * @Version 1.0.0
 */
@Service(interfaceClass = OrderService.class)
@Transactional
public class OrderServiceImpl implements OrderService {

    @Autowired
    private OrderDao orderDao;

    @Autowired
    private OrderSettingDao orderSettingDao;

    @Autowired
    private MemberDao memberDao;

    @Override
    public Result submit(OrderInfo orderInfo) throws OrderException{

        Date orderDate = orderInfo.getOrderDate();
        String telephone = orderInfo.getPhoneNumber();
        String name = orderInfo.getName();
        String sex = orderInfo.getSex();
        String idCard = orderInfo.getIdCard();

        int setmealId = orderInfo.getSetmealId();
        String orderType = orderInfo.getOrderType();

        //1.根据订单日期先查询当天是否存在预约设置
        OrderSetting orderSetting = orderSettingDao.findByDate(orderDate);
        if (orderSetting == null) {
            //如果没有预约设置，则返回提示信息：当天不能预约
            return Result.error(MessageConstant.SELECTED_DATE_CANNOT_ORDER);
        }

        //2.判断当日是否已经约满
        int number = orderSetting.getNumber();
        int reservations = orderSetting.getReservations();
        if (reservations >= number) {
            //当已预约数大于等于可预约数时，返回提示信息：已经约满
            return Result.error(MessageConstant.ORDER_FULL);
        }

        //3.查询该手机号是否为公司会员,并获取会员id
        Member member = memberDao.findByTelephone(telephone);
        member = isMember(telephone, name, sex, idCard, member);
        Integer memberId = member.getId();

        //4.根据会员id，套餐id，预约时间 查询是否已经预约过
        Order order = new Order();
        order.setMemberId(memberId);
        order.setSetmealId(setmealId);
        order.setOrderDate(orderDate);
        order.setOrderType(orderType);
        order.setOrderStatus(Order.ORDERSTATUS_NO);
        List<Order> orders = orderDao.findByCondition(order);
        if (CollectionUtil.isNotEmpty(orders)) {
            //存在预约，则返回提示消息：不能重复预约
            return Result.error(MessageConstant.HAS_ORDERED);
        }

        //5.不存在，则存储该预约信息，并更新预约设置表中的已经预约数
        orderDao.add(order);
        int row = orderSettingDao.updateReservasionsByIdAndVersion(orderSetting.getId(),orderSetting.getVersion());
        if (row != 1) {
            //插入失败，则抛出异常
            throw new OrderException("更新失败");
        }
        //6.返回提示信息：预约成功,并返回订单对象
        return Result.success(MessageConstant.ORDER_SUCCESS,order);
    }

    @Override
    public Map findById(Integer id) {
        return orderDao.findById4Detail(id);
    }

    @Override
    public void updatePayNo(String outTradeNo, Integer orderId) {
        orderDao.updatePayNo(outTradeNo, orderId);
    }

    @Override
    public void updatePayStatus(String outTradeNo) {
        orderDao.updatePayStatus(outTradeNo);
    }

    @Override
    public Result addByPhone(OrderSettingList orderSettingList) {
        Date orderDate = orderSettingList.getOrderDate();
        String telephone = orderSettingList.getPhoneNumber();
        String name = orderSettingList.getName();
        String sex = orderSettingList.getSex();
        String idCard = orderSettingList.getIdCard();

        int setmealId = orderSettingList.getSetmealId();
        String orderType = orderSettingList.getOrderType();

        //1.根据订单日期先查询当天是否存在预约设置
        OrderSetting orderSetting = orderSettingDao.findByDate(orderDate);
        if (orderSetting == null) {
            //如果没有预约设置，则返回提示信息：当天不能预约
            return Result.error(MessageConstant.SELECTED_DATE_CANNOT_ORDER);
        }

        //2.判断当日是否已经约满
        int number = orderSetting.getNumber();
        int reservations = orderSetting.getReservations();
        if (reservations >= number) {
            //当已预约数大于等于可预约数时，返回提示信息：已经约满
            return Result.error(MessageConstant.ORDER_FULL);
        }

        //3.查询该手机号是否为公司会员,并获取会员id
        Member member = memberDao.findByTelephone(telephone);
        member = isMember(telephone, name, sex, idCard, member);
        Integer memberId = member.getId();

        //4.根据会员id，套餐id，预约时间 查询是否已经预约过
        Order order = new Order();
        order.setMemberId(memberId);
        order.setSetmealId(setmealId);
        order.setOrderDate(orderDate);
        order.setOrderType(orderType);
        order.setOrderStatus(Order.ORDERSTATUS_NO);
        List<Order> orders = orderDao.findByCondition(order);
        if (CollectionUtil.isNotEmpty(orders)) {
            //存在预约，则返回提示消息：不能重复预约
            return Result.error(MessageConstant.HAS_ORDERED);
        }

        //5.不存在，则存储该预约信息，并更新预约设置表中的已经预约数
        orderDao.addByPhone(order);
        int row = orderSettingDao.updateReservasionsByIdAndVersion(orderSetting.getId(),orderSetting.getVersion());
        if (row != 1) {
            //插入失败，则抛出异常
            throw new OrderException("更新失败");
        }
        //6.返回提示信息：预约成功,并返回订单对象
        return Result.success(MessageConstant.ORDER_SUCCESS,order);
    }

    private Member isMember(String telephone, String name, String sex, String idCard, Member member) {
        if (member == null) {
            //不是则注册为会员
            member = new Member();
            member.setPhoneNumber(telephone);
            member.setName(name);
            member.setSex(String.valueOf(sex));
            member.setIdCard(idCard);
            member.setRegTime(new Date());
            if (member.getBirthday()==null) {
                DateTime birthday ;
                if (idCard != null) {
                    String birthdayStr = idCard.substring(7, 15);
                    birthday = DateUtil.parse(birthdayStr, "yyyyMMdd");
                } else {
                    birthday=new DateTime();
                }
                member.setBirthday(birthday);
            }
            memberDao.add(member);
        }
        return member;
    }

    @Override
    public PageResult findPage(QueryPageBean queryPageBean) {
        Page<Object> page = PageHelper.startPage(queryPageBean.getCurrentPage(), queryPageBean.getPageSize());

        //2.写一个普通的跟分页无关的查询
        List<OrderSettingList> orderSettingLists = orderDao.findPage(queryPageBean.getQueryString());
        return new PageResult(page.getTotal(),orderSettingLists);
    }
}
